package com.winbomb.kingcard.base.ai;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

import android.util.Log;

import com.winbomb.kingcard.Action;
import com.winbomb.kingcard.IBattle;
import com.winbomb.kingcard.ICard;
import com.winbomb.kingcard.IForce;
import com.winbomb.kingcard.IGameLogic;
import com.winbomb.kingcard.IPlayer;
import com.winbomb.kingcard.IState;
import com.winbomb.kingcard.INegotiate.NegoResult;
import com.winbomb.kingcard.base.BattleState;
import com.winbomb.kingcard.base.Card;
import com.winbomb.kingcard.base.Force;
import com.winbomb.kingcard.base.GameLogic;
import com.winbomb.kingcard.base.GameState;
import com.winbomb.kingcard.utils.GameUtils;

public class AIThread implements Runnable {

	private static final String TAG = "AIThread";

	/** 线程休息的时间 */
	public int sleepTime = 50;

	private IGameLogic game;
	private IPlayer player;
	private IState gameSt;

	private static final Random rand = new Random();

	/** 进攻目标 */
	private IPlayer atkTarget;
	/** 派遣目标 */
	private IPlayer sendTarget;
	/** 征召目标 */
	private IPlayer callSource;

	/**
	 * isWorkDone标志本次工作是否完成,它保证每个步骤只进行一次思考, 否则
	 * 
	 * 可能出现一个状态思考多次的混乱局面.
	 */
	private boolean isWorkDone;

	private static final int[] POINTS = new int[] { 200, 300, 400, 600, 700, 600, 700, 700, 800, 800, 800, 800, 900,
			900, 900, 1000 };

	public AIThread(IGameLogic game) {
		this.game = game;
		this.player = game.getCurrPlayer();
		this.isWorkDone = true;
	}

	public void work() {
		this.isWorkDone = false;
	}

	@Override
	public void run() {
		while (game != null && !game.isStopped()) {

			player = game.getCurrPlayer();
			IBattle battle = game.getBattle();

			if (player.isHuman() || game.isPaused() || isWorkDone) {
				try {
					Thread.sleep(sleepTime);
				} catch (InterruptedException ex) {
					ex.printStackTrace();
				}

				continue;
			}

			gameSt = game.getState();
			Log.i(TAG, "GameState: " + gameSt);

			if (gameSt == GameState.SELECT_ACTION) {
				// 选择下一步行动
				Action action = thinkNextAction();
				player.setAction(action);

			} else if (gameSt == GameState.SELECT_CHANGE_CARD) {
				// 修养过程中选择变换的卡片
				ICard card = getLeastValuableCard();
				card.setSelected(true);

			} else if (gameSt == GameState.SELECT_TARGET) {
				// 选择进攻的目标
				player.setAttackTarget(atkTarget);

			} else if (gameSt == GameState.SELECT_ATK_CARDS || gameSt == GameState.SELECT_DEF_CARDS) {
				selectRandomCards(player.getCards(), GameLogic.MAX_PLAY_CARD);

			} else if (gameSt == GameState.BEGIN_NEGOTIATE) {
				negotiate();

			} else if (gameSt == GameState.SELECT_SENDOUT_TARGET) {
				player.setSendTarget(sendTarget);

			} else if (gameSt == GameState.SELECT_SENDOUT_CARDS) {
				selectRandomCards(player.getCards(), player.getSendTarget().isAlive() ? 2 : 3);

			} else if (gameSt == GameState.SELECT_CALLUP_SOURCE) {
				player.setCallSource(callSource);

			} else if (gameSt == BattleState.SELECT_ATK_TARGET) {
				selectTargetCard(game.getBattle().getAtkableTargets());

			} else if (gameSt == BattleState.INVADER_SET_GENERAL || gameSt == BattleState.GUARDER_SET_GENERAL) {
				// 选择点数最大的将进行叫阵
				selectGeneral(battle.getAtkCards());

			} else if (gameSt == BattleState.OFFENSIVE_ARRAY || gameSt == BattleState.DEFENSIVE_ARRAY) {
				// 摆阵,这里用随机打乱顺序的算法
				GameUtils.shuffleCards(battle.getAtkCards());

			} else if (gameSt == BattleState.SELECT_ATK_CARD) {
				// 选择进攻卡片
				selectAtkCard(battle.getAtkCards());

			} else if (gameSt == BattleState.CHASE_AND_ATTACK) {
				// 选择是否追击
				boolean isChase = selectChaseOrNot();
				player.setAction(isChase ? Action.CHASE_ATTACK : Action.WITHDRAW);

			} else if (gameSt == BattleState.SELECT_CHASE_CARDS) {
				// 选择用于追击的牌
				selectChaseCards(player.getBattleCards());

			}

			player.setDone(true);
			isWorkDone = true;

			if (gameSt == GameState.DEFEATED || gameSt == GameState.VICTORY) {

			}
		}
	}

	/**
	 * 选择是否进行追击
	 * 
	 * @return
	 */
	private boolean selectChaseOrNot() {

		List<ICard> battleCards = player.getBattleCards();
		// 如果战牌少于4个, 不进行追击
		if (battleCards.size() < 4) {
			return false;
		}

		// 如果被追击的对象的手牌少于等于3张,可追击的牌又大于等于4张,则追击之
		IPlayer target = game.getBattle().getLoser();
		if (target.getCardCount() <= 3 && battleCards.size() >= 4) {
			return true;
		}

		// 如果自己的手牌太少了,不进行追击
		if (player.getCardCount() + battleCards.size() < 8) {
			return false;
		}

		// 如果牌太水了,不进行追击
		boolean hasGeneral = false;
		int totalPoint = 0;
		for (ICard card : battleCards) {
			if (card.getPoint() > 10) {
				hasGeneral = true;
			}
			totalPoint += card.getPoint();
			if (card.getPoint() == 1 || card.getPoint() == 2) {
				totalPoint += 10;
			}
		}

		if (!hasGeneral || totalPoint < 50) {
			return false;
		}

		return true;
	}

	private void negotiate() {

		IPlayer srcPlayer = game.getBattle().getInvoker();
		IPlayer tgPlayer = game.getBattle().getTarget();

		if (player.getMaster() == tgPlayer) {
			// 如果player和要攻击的目标是相同的势力,则拒绝之
			game.getNegotiate().setResult(NegoResult.DENY);
		} else if (player.getForce().hasRelation(tgPlayer.getForce(), Force.RT_ALEIN)) {
			game.getNegotiate().setResult((player.getCardCount() >= 8) ? NegoResult.DENY : NegoResult.REQUIRE);

		} else if (player.getForce().hasRelation(srcPlayer.getForce(), Force.RT_ALEIN) || srcPlayer.getCardCount() == 0) {
			// 如果player和进攻发起者是同盟,则放其通过
			game.getNegotiate().setResult(NegoResult.AGREE);

		} else {
			game.getNegotiate().setResult(NegoResult.REQUIRE);
		}

	}

	private static void selectChaseCards(List<ICard> chaseCards) {
		int count = 0;
		for (int i = 0; i < chaseCards.size() && count < GameLogic.MAX_PLAY_CARD; i++) {
			chaseCards.get(i).setSelected(true);
		}
	}

	/**
	 * 选择进攻卡片
	 * 
	 * 
	 * @param atkCards
	 * @return
	 */
	private static void selectAtkCard(ICard[] atkCards) {
		for (int i = 0; i < atkCards.length; i++) {
			if (atkCards[i] != null && atkCards[i].testFlag(Card.IS_UNOPEN_CARD)) {
				atkCards[i].setSelected(true);
				return;
			}
		}
	}

	private static void selectGeneral(ICard[] atkCards) {
		ICard general = null;
		for (ICard card : atkCards) {
			if (card == null || card.getPoint() <= 10) {
				continue;
			}

			if (general == null || card.getPoint() > general.getPoint()) {
				general = card;
			}
		}

		if (general != null) {
			general.setFlag(Card.IS_GENERAL);
		}
	}

	private static void selectTargetCard(ICard[] tgCards) {

		List<ICard> recomList = new ArrayList<ICard>(4);
		// 如果有翻开的卡片可以攻击,则选择这张翻开的卡片进行攻击
		for (int i = 0; i < tgCards.length; i++) {
			if (tgCards[i].testFlag(Card.IS_FIRST_CHOICE)) {
				tgCards[i].setSelected(true);
				return;
			} else if (tgCards[i].testFlag(Card.IS_RECOMMENDED)) {
				recomList.add(tgCards[i]);
			}
		}

		// 有推荐的牌,就从推荐的牌中选择一张,否则随便选择一个.
		ICard tgCard = tgCards[rand.nextInt(tgCards.length)];
		if (recomList.size() > 0) {
			Collections.shuffle(recomList);
			tgCard = recomList.get(0);
		}

		tgCard.setSelected(true);
	}

	private static void selectRandomCards(ICard[] cards, int cardCnt) {

		// 简单的AI,随机选择五张牌
		ICard[] sltCards = GameUtils.selectRandomCard(cards, cardCnt);

		for (ICard card : sltCards) {
			if (card != null) {
				card.setSelected(true);
			}
		}
	}

	private Action thinkNextAction() {

		Action action = null;
		sendTarget = null;
		callSource = null;
		atkTarget = null;

		// 选择派遣的条件
		if (player.getCardCount() >= 10 && player.getActionMask()[2]) {

			// 如果有兵力小于4的快要垮掉的所属势力,派遣援助之
			for (IPlayer tgPlayer : game.getPlayers()) {
				if (tgPlayer.getMaster() == player && tgPlayer.isAlive() && tgPlayer.getCardCount() <= 5) {
					if (sendTarget == null || tgPlayer.getCardCount() < sendTarget.getCardCount()) {
						sendTarget = tgPlayer;
					}
				}
			}

			if (sendTarget != null) {
				return Action.SEND_OUT;
			}

			// 如果有可以复活的势力,则复活之
			for (IPlayer tgPlayer : game.getPlayers()) {
				if (!tgPlayer.isAlive() && (tgPlayer.getMaster() == player || tgPlayer.getMaster() == null)) {
					if (sendTarget == null) {
						sendTarget = tgPlayer;
					} else {
						int leftDis1 = GameUtils.getLeftDistance(player, sendTarget);
						int rightDis1 = GameUtils.getRightDistance(player, sendTarget);
						int dis1 = (leftDis1 < rightDis1) ? leftDis1 : rightDis1;

						int leftDis2 = GameUtils.getLeftDistance(player, tgPlayer);
						int rightDis2 = GameUtils.getRightDistance(player, tgPlayer);
						int dis2 = (leftDis2 < rightDis2) ? leftDis2 : rightDis2;

						sendTarget = (dis2 < dis1) ? tgPlayer : sendTarget;
					}
				}
			}

			if (sendTarget != null) {
				return Action.SEND_OUT;
			}
		}

		// 如果主公的牌少于6张,则要找所属势力中牌大于8的中牌最多的征召
		// 如果势力中有某个势力异常强大,对主公造成威胁,则征召之
		if (player.getActionMask()[3]) {
			int thresHold = (player.getCardCount() <= 6) ? 8 : 14;

			for (IPlayer tgPlayer : game.getPlayers()) {
				if (tgPlayer.getMaster() == player && tgPlayer != player && tgPlayer.isAlive()
						&& tgPlayer.getCardCount() >= thresHold) {
					if (callSource == null || callSource.getCardCount() < tgPlayer.getCardCount()) {
						callSource = tgPlayer;
					}
				}
			}

			if (callSource != null) {
				return Action.CALL_UP;
			}
		}

		if (player.getCardCount() >= 10 && player.getActionMask()[4]) {
			return Action.TAKE_POWER;
		}

		atkTarget = thinkAttackTarget();
		action = (atkTarget == null) ? Action.REST : Action.BATTLE;

		return action;
	}

	private IPlayer thinkAttackTarget() {

		// 刷新当前的形式
		updateSituation();

		// 找到左右两侧可以攻击的目标
		IPlayer rightTarget = player.getRightAlivePlayer();
		while (rightTarget.getForce().hasRelation(player.getForce(), Force.RT_ALEIN) && rightTarget != player) {
			rightTarget = rightTarget.getRightAlivePlayer();
		}

		IPlayer leftTarget = player.getLeftAlivePlayer();
		while (leftTarget.getForce().hasRelation(player.getForce(), Force.RT_ALEIN) && leftTarget != player) {
			leftTarget = leftTarget.getLeftAlivePlayer();
		}

		int point = GameUtils.evaluate(player.getCards());

		// 如果两边都适宜出击,选择牌少的一边进行出击
		int rightPointThreshold = POINTS[rightTarget.getCardCount() > 15 ? 15 : rightTarget.getCardCount()];
		int leftPointThreshold = POINTS[leftTarget.getCardCount() > 15 ? 15 : leftTarget.getCardCount()];
		if (point > rightPointThreshold && point > leftPointThreshold) {
			return (leftTarget.getCardCount() <= rightTarget.getCardCount()) ? leftTarget : rightTarget;

		} else if (point > rightPointThreshold) {
			return rightTarget;

		} else if (point > leftPointThreshold) {
			return leftTarget;

		}

		return null;
	}

	/**
	 * 刷新当前的局势
	 */
	private void updateSituation() {

		// 获取所有的势力
		List<IForce> forces = new ArrayList<IForce>();
		for (IPlayer onePlayer : game.getPlayers()) {
			if (onePlayer.getMaster() == onePlayer) {
				forces.add(onePlayer.getForce());
			}
		}

		// 对势力进行排序(按照兵力的大小排序)
		Collections.sort(forces, new ForceComparator());

		// 清除之前的同盟/敌对关系
		for (IForce force : forces) {
			force.clearRelations();
			force.setAleinFlag(-1);
		}

		/*
		 * 以0.6为阈值,如果后面势力的兵力小于最多兵力的0.6,则后面的玩家
		 * 
		 * 组成联盟
		 */
		int mostCardCnt = forces.get(0).getCardCount();
		int aleinIdx = forces.size();
		for (int i = 0; i < forces.size(); i++) {
			int cardCnt = forces.get(i).getCardCount();
			if (cardCnt < mostCardCnt * 0.6) {
				aleinIdx = i;
				break;
			}
		}

		// 设置同盟关系,使其不相互攻击
		for (int i = aleinIdx; i < forces.size(); i++) {
			for (int j = i + 1; j < forces.size(); j++) {
				forces.get(i).setRelation(forces.get(j), Force.RT_ALEIN);
				forces.get(j).setRelation(forces.get(i), Force.RT_ALEIN);
			}
		}

		// 设置同盟旗帜
		if (aleinIdx < forces.size() - 1) {
			int flag = forces.get(aleinIdx).getForceFlag();
			for (int i = aleinIdx; i < forces.size(); i++) {
				forces.get(i).setAleinFlag(flag);
			}
		}
	}

	/**
	 * 获得最没价值的牌，用于丢弃
	 * 
	 * @return
	 */
	private ICard getLeastValuableCard() {
		ICard[] cards = player.getCards();
		return cards[cards.length - 1];
	}

	class ForceComparator implements Comparator<IForce> {

		@Override
		public int compare(IForce force1, IForce force2) {

			if (force1 == force2) {
				return 0;
			}

			int deltaCard = force2.getCardCount() - force1.getCardCount();
			if (deltaCard != 0) {
				return deltaCard;
			}

			return force2.getMemeberCount() - force1.getMemeberCount();
		}

	}
}
